package com.mybatis.framework.registrar;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.util.CollectionUtils;
import org.springframework.web.servlet.DispatcherServlet;

import com.mybatis.framework.factoybean.MybatisFactoryBean;
import com.mybatis.framework.utils.FileUtil;
import com.mybatis.framework.utils.StringUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * com.mybatis.framework.registrar
 *
 * @author humdeef
 * @since 2019-07-14
 */
@Slf4j
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

  private static String path_suffix = "";

  static {
    path_suffix = DispatcherServlet.class.getResource("/").getPath();
  }

  @Override
  public void registerBeanDefinitions(AnnotationMetadata annotationMetadata,
      BeanDefinitionRegistry beanDefinitionRegistry) {


    // 通过注解名字拿到 该注解里面的key-value
    Map<String, Object> mapperScan =
        annotationMetadata.getAnnotationAttributes("com.mybatis.framework.anno.MapperScan");

    if (Objects.nonNull(mapperScan)) {
      // 获取到包名
      String packageName = mapperScan.get("value").toString();
      String path = path_suffix + packageName.replaceAll("\\.", "/");
      List<String> packages = new ArrayList<>();
      // 通过类路径获取每个包名
      FileUtil.getPackageClazz(packages, path);
      // 通过包名 获取到包里面的对象
      try {
        if (!CollectionUtils.isEmpty(packages)) {
          // 依次将类添加到spring 容器中
          for (String classPath : packages) {
            String className = classPath.replaceAll(".class", "");
            // 获取到类信息
            Class clazz = Class.forName(className);
            String lowerFirstLetter = StringUtil.lowerFirstLetter(clazz.getSimpleName());
            BeanDefinitionBuilder beanDefinitionBuilder =
                BeanDefinitionBuilder.genericBeanDefinition(MybatisFactoryBean.class);
            AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
            // 添加构造器参数,将类传到MybatisFactoryBean 中
            beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(clazz);
            beanDefinitionRegistry.registerBeanDefinition(lowerFirstLetter, beanDefinition);
          }
        }
      } catch (Exception e) {
        log.error(" class  resolution error:{}", e);
      }
    }
  }
}
